#ifdef HAS_SET_KEYS

// The key that is being currently set.
public static byte currentKeySet = -1;

// Para ver si el usuario toco o no alguna tecla.
public static boolean setFinished = false;
public static boolean setStarted = false;

// recursos de este estado.
static Image dpad;

// D-Pad and buttons dimensions.
public static int SKL_X;
public static int SKR_X;
public static int SK_Y;

public static int DPAD_X;
public static int DPAD_Y;

public static int arrowsOffset;

public static int AVAILABLE_WIDTH;

// Colors used in the set key screen.

// Color for the buttons.
public static int butColor;
public static int butHighColor;
public static int butFontColor;
public static int frameColor;

// The margin from the screen edge to the frame draw.
public int frameMarginFromEdge;

public void initButValues() 
{
	setKeysInitDimensions();
	setKeysInitColors();
}

public void setKeysInitColors() 
{
	backgroundColor	= 0xffffff;
	frameColor 		=~ backgroundColor;
}

public void setKeysInitDimensions() 
{
	// calculo el 10% del menor de las dimensiones de la pantalla para asegurarme que entre.
	float aux = SCREEN_MIN_EDGE / 100 * 13; //TODO: traelo de lo exportado por DIDI.
	titleY = SCREEN_HEIGHT >> 3; // TODO:Traerlo de lo exportado por DIDI. 
	SKL_X = sKMarginFromEdge;
	SKR_X = SCREEN_WIDTH - sKMarginFromEdge - arrow.getHeight();
	SK_Y = SCREEN_HEIGHT - sKMarginFromEdge - arrow.getWidth(); // TODO: no harcodear.
	DPAD_Y = SCREEN_HEIGHT - (dpad.getHeight() >> 1) - (dpad.getHeight() >> 3) ;
	DPAD_X = SCREEN_WIDTH >> 1;
	arrowsOffset = (dpad.getWidth() >> 2) + (dpad.getWidth() >> 4);
	AVAILABLE_WIDTH = SCREEN_WIDTH - (SCREEN_WIDTH >> 2);
	movementOffset = 0;
}

/**
 *  Will be called when the set key state is set.
 * */
public void updateSetKeys() 
{
	if (subState == STATES.INIT) 
	{
		initButValues();
		subState = STATES.UPDATE;
	}
	else 
	{
		updateMovementOffset();
		setKeysListenToUserEvents();
		setKeysDrawBg();
		setKeysDrawMessages();
		setKeysDrawButtons();
	}
}

/**
 * Draws the background of the screen.
 * */
public void setKeysDrawBg() 
{
	cGame_g.setClip(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
	cGame_g.setColor(backgroundColor);
	cGame_g.fillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
	cGame_g.setColor(frameColor);
	int x = 5, y = 6, ar = 20, bw = 2;
	cGame_g.drawRoundFrame(x, y, SCREEN_WIDTH - 2 * x, SCREEN_HEIGHT -  2 * y, ar, ar, bw);
}

/**
 * Draws the messages to the user. It will tell the user what to do, step by step.
 * */
public void setKeysDrawMessages() 
{
	int spacing = cGame_g.getFontHeight() + lineSpacing;
	int y = titleY;
	int x = SCREEN_WIDTH >> 1;
	byte lines;
	int anchor = DSmallFont.BOTTOM | DSmallFont.HCENTER; 
	// Escribo el titulo.
	cGame_g.drawString(TEXT.KEY_SET_MESSAGES[TEXT.TITLE_IDX], x, y, anchor);
	y += spacing;
	if (!setStarted) 
	{
		cGame_g.drawString(TEXT.KEY_SET_MESSAGES[TEXT.PRESS_ANY_KEY_IDX], x, SCREEN_HEIGHT >> 1, AVAILABLE_WIDTH, anchor);
	} 
	else 
	{
		lines = cGame_g.drawString(TEXT.KEY_SET_MESSAGES[TEXT.PRESS_THE_KEY_IDX], x, y, AVAILABLE_WIDTH, anchor);
		y += lines * cGame_g.getFontHeight(); 
		cGame_g.drawString(TEXT.KEY_SET_NAMES[currentKeySet], x, y += spacing, anchor);
	}
}

/**
 * Draw the buttons of the setKeys state. The current button is draw in a different color.
 * */
public void setKeysDrawButtons() 
{
	cGame_g.setClip(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
	if (!setStarted) return;
	// Borde dpad.
	cGame_g.drawRegion(dpad, 0, 0, dpad.getWidth(), dpad.getHeight(), Sprite.TRANS_NONE, DPAD_X, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
	// LSK
	if (currentKeySet != KEYS.IDX_LSK) cGame_g.drawRegion(arrow, 0,0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_ROT270, SKL_X, SK_Y, 0);
	// RSK
	if (currentKeySet != KEYS.IDX_RSK) cGame_g.drawRegion(arrow, 0,0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_ROT270, SKR_X, SK_Y, 0);
	// Arriba
	if (currentKeySet != KEYS.IDX_UP) cGame_g.drawRegion(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_ROT90, DPAD_X, DPAD_Y - arrowsOffset, Graphics.HCENTER | Graphics.VCENTER);
	// Abajo
	if (currentKeySet != KEYS.IDX_DOWN) cGame_g.drawRegion(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_ROT270, DPAD_X, DPAD_Y + arrowsOffset, Graphics.HCENTER | Graphics.VCENTER);
	// Izq
	if (currentKeySet != KEYS.IDX_LEFT) cGame_g.drawRegion(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_NONE, DPAD_X - arrowsOffset, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
	// Der
	if (currentKeySet != KEYS.IDX_RIGHT) cGame_g.drawRegion(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), Sprite.TRANS_ROT180, DPAD_X + arrowsOffset, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
	// Ok
	if (currentKeySet != KEYS.IDX_FIRE) cGame_g.drawRegion(okBut, 0, 0, okBut.getWidth(), okBut.getHeight(), Sprite.TRANS_NONE, DPAD_X, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
	
	// Dibujo la tecla actual con otro color. 
	switch (currentKeySet) 
	{
		case KEYS.IDX_LSK:
			cGame_g.drawRegion(arrowSelected, 0,0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_ROT270, SKL_X, SK_Y - movementOffset, 0);
			break;
		case KEYS.IDX_RSK:
			cGame_g.drawRegion(arrowSelected, 0,0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_ROT270, SKR_X, SK_Y - movementOffset, 0);
			break;
		case KEYS.IDX_UP:
			cGame_g.drawRegion(arrowSelected, 0, 0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_ROT90, DPAD_X, DPAD_Y - arrowsOffset - movementOffset, Graphics.HCENTER | Graphics.VCENTER);
			break;
		case KEYS.IDX_DOWN:
			cGame_g.drawRegion(arrowSelected, 0, 0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_ROT270, DPAD_X, DPAD_Y + arrowsOffset - movementOffset, Graphics.HCENTER | Graphics.VCENTER);
			break;
		case KEYS.IDX_LEFT:
			cGame_g.drawRegion(arrowSelected, 0, 0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_NONE, DPAD_X - arrowsOffset - movementOffset, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
			break;
		case KEYS.IDX_RIGHT:
			cGame_g.drawRegion(arrowSelected, 0, 0, arrowSelected.getWidth(), arrowSelected.getHeight(), Sprite.TRANS_ROT180, DPAD_X + arrowsOffset - movementOffset, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
			break;
		case KEYS.IDX_FIRE:
			cGame_g.drawRegion(okButSelected, 0, 0, okButSelected.getWidth(), okButSelected.getHeight(), Sprite.TRANS_NONE, DPAD_X, DPAD_Y, Graphics.HCENTER | Graphics.VCENTER);
			break;
	}
}

/**
 * Listens the actions from the user.
 * */
public void setKeysListenToUserEvents() 
{
	if (newEvent)
	{
		if (!setStarted) 
		{
			currentKeySet = 0;
			setStarted = true;
			return;
		}
		if (currentKeySet < INTERFACE.NECESSARY_KEYS) 
		{
			KEYS.SET[currentKeySet] = lastKeyCode;
			if (currentKeySet < INTERFACE.NECESSARY_KEYS - 1) 
			{
				currentKeySet++;
			} 
			else 
			{
				setFinished = true;
			}
			clearKeys();
		} 
		else 
		{
		#ifdef HAS_TEAM_SELECTION
			setState(STATES.TEAM_SELECTION);
		#else
			setState(STATES.TEMPLATE_HANDLER);
		#endif
		}
	}
	else
	{
		if (setFinished)
		{
			String data = ""; 
			
			for (int i = 0 ; i < KEYS.SET.length ; ++i)
			{
				data = data + KEYS.SET[i] + ",";
			}
			
			rmsSave(RMS_INFO.KEY_SET, data.getBytes());
			
			#ifdef HAS_TEAM_SELECTION
			setState(STATES.TEAM_SELECTION);
			#else
			setState(STATES.TEMPLATE_HANDLER);
			#endif
		}
	}
}

#endif